/*
 * @ShutdownHook.java   2008/11/02
 *
 * Copyright 2008 Web & Zen Multimedia, All rights reserved.
 * Use is subject to license terms.
 */
package it.wzm.lightweightlog;

import java.util.Arrays;
import java.util.LinkedList;

/**
 * Our shutdown hook accessible only from package, as required by the rule of hooking it's extending the Thread class
 * and therefore overridding run method.
 * 
 * @author Leonardo Celati
 */
class ShutdownHook extends Thread {
	
	/**
	 * Default constructor
	 */
	public ShutdownHook() {
    }
	
	/**
	 * As required by the rule of shutdown hook, it's implementing 
	 */
	@Override
    public void run() {
    	// cleanup...but only if we are not already in shutdown mode...
    	//if (!LogFactory.getStatus().equals("SHUTDOWN") )
    		shutdown();
    }
    
    /**
     * Free resources...
     */
    @SuppressWarnings("unchecked")
	private static void shutdown() {    
    	
    	//switch (LogFactory.getStatus()) {
    	
    	//case LogFactory.Status.RUNNING {
    	
	    	//Log l = LogFactory.getLog();
    		Log l = LogFactory.newLogger(ShutdownHook.class.getName());
    		LogPool lp = LogFactory.getLogPool();
	        QueueDumper qd = LogFactory.getQueueDumper();
	        Queue<? extends Entry> q = LogFactory.getQueue();
	        Register<? extends Dumper> r = LogFactory.getRegister();

	        // just a note...
	        l.debug("------------------------------------------");
	        l.debug("Lightweightlog closed properly");
	        l.debug("------------------------------------------");
	        
	        // shutdown QueueDumper
	    	// it is not always running...
	    	if (qd != null) {    		
	    		try {
	    			qd.shutdown();
	    		} catch (RuntimeException e) {
	    			
	    			// we know that the qd will launch a RuntimeException 
	    			// if it is not able to stop itself, in this case we look for it
	    			// the group and interrupt, later we wil take care of Queue.
		        	ThreadGroup g = Thread.currentThread().getThreadGroup();            	
		        	Thread[] T = new Thread[g.activeCount()];
		        	g.enumerate(T, false);
		        	
		        	qdshutdown:
		        	for (Thread x: Arrays.asList(T)) {
		        		// if it's found...we break the loop
		        		// before we interrupt the thread...
		        		if (x.getName().equals("QueueDumper")) {
		        			x.interrupt();
		        			break qdshutdown;
		        		}
		        	}	    			
	    		}
	        	
	    	}
	    	
	        // before shutdown we try to clear any entry we may have in log    	
	    	if (!q.isEmpty()) {
	    		LinkedList<? extends Entry> ll = q.retainAll();
	    		r.dispatchToDumper(ll);
	    	}
	    	// now we close register and the rest...
	    	
	    	r.shutdown();
	    	r = null;     
	        q = null;
	        l = null;
	        
	        //break;
    	}
    //}    
    
    
}
